//
//  STImagePicker.swift
//
//  The MIT License (MIT)
//
//  Copyright (c) 2021 沈天
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all
//  copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//  SOFTWARE.

import UIKit
import TZImagePickerController

public class STImagePicker: NSObject{
    
    // MARK: 1.lift cycle
    public static var shared = STImagePicker()
    
    deinit {
        imagePickerBlock = nil
        print("-------- STImagePicker deinit --------")
    }
    // MARK: 2.private methods
    /// 2.1 获取头像方法, 剪切为正方形头像
    public func imagePickerHeadIcon(completion: @escaping ((UIImage) -> ())){
        allowCrop = true
        imagePickerBlock = completion
        STAlertView.show(title: nil, message: nil, titleOne: "从相册选择", titleTwo: "拍照", cancelTitle: "取消") { (flag) in
            if flag == 1 {
                let imagePickerVc:TZImagePickerController = TZImagePickerController.init(maxImagesCount: 1, delegate: nil)
                imagePickerVc.allowCrop = self.allowCrop
                imagePickerVc.allowPreview = true
                imagePickerVc.allowTakePicture = false
                imagePickerVc.allowCameraLocation = false
                imagePickerVc.allowPickingVideo = false
                if UIDevice.isPad {
                    imagePickerVc.modalPresentationStyle = .fullScreen
                }
                imagePickerVc.didFinishPickingPhotosHandle = { (photos, assets, isSelectOriginalPhoto) in
                    if photos?.count ?? 0 > 0 {
                        self.imagePickerBlock?(photos!.first!)
                    }
                }
                self.fromController.present(imagePickerVc, animated: true, completion: nil)
            }else if flag == 2 {
                self.selectPhoto()
            }
        }
    }
    
    /// 2.2 获取单张图片, 支持原图选择
    public func imagePickerSingle(completion: @escaping ((UIImage) -> ())){
        imagePickerBlock = completion
        allowCrop = false
        STAlertView.show(title: nil, message: nil, titleOne: "从相册选择", titleTwo: "拍照", cancelTitle: "取消") { (flag) in
            if flag == 1 {
                let imagePickerVc:TZImagePickerController = TZImagePickerController.init(maxImagesCount: 1, delegate: nil)
                imagePickerVc.allowCrop = self.allowCrop
                imagePickerVc.allowPreview = true
                imagePickerVc.allowTakePicture = false
                imagePickerVc.allowCameraLocation = false
                imagePickerVc.allowPickingVideo = false
                if UIDevice.isPad {
                    imagePickerVc.modalPresentationStyle = .fullScreen
                }
                imagePickerVc.didFinishPickingPhotosHandle = { (photos, assets, isSelectOriginalPhoto) in
                    if isSelectOriginalPhoto {
                        getImage(asset: assets?.first as! PHAsset)
                    }else{
                        self.imagePickerBlock?(photos!.first!)
                    }
                }
                self.fromController.present(imagePickerVc, animated: true, completion: nil)
            }else if flag == 2 {
                self.selectPhoto()
            }
        }
        
        func getImage(asset: PHAsset){
            TZImageManager.default()?.getOriginalPhoto(with: asset, completion: { (image, dic) in
                self.imagePickerBlock?(image!)
            })
        }
    }
    
    /// 2.3 获取多张图片, 支持原图选择，最少一张图，默认9张图
    public func imagePickerMore(maxImagesCount:Int, completion: @escaping (([UIImage]) -> ())){
        imagePickersBlock = completion
        allowCrop = false
        let imagePickerVc:TZImagePickerController = TZImagePickerController.init(maxImagesCount: maxImagesCount, delegate: nil)
        imagePickerVc.allowCrop = false
        imagePickerVc.allowPreview = true
        imagePickerVc.allowTakePicture = true
        imagePickerVc.allowCameraLocation = false
        imagePickerVc.allowPickingVideo = false
        if UIDevice.isPad {
            imagePickerVc.modalPresentationStyle = .fullScreen
        }
        imagePickerVc.didFinishPickingPhotosHandle = { (photos, assets, isSelectOriginalPhoto) in
            if isSelectOriginalPhoto {
                var images = [UIImage]()
                for asset in assets ?? []{
                    let phAsset = asset as! PHAsset
                    TZImageManager.default()?.getOriginalPhoto(with: phAsset, completion: { (image, dic) in
                        images.append(image!)
                        if images.count == assets?.count{
                            self.imagePickersBlock?(images)
                        }
                    })
                }
            }else{
                self.imagePickersBlock?(photos ?? [])
            }
        }
        fromController.present(imagePickerVc, animated: true, completion: nil)
    }
    
    // MARK: 3.event response
    public func selectPhoto(){
        if  UIDevice.isSimulator {
            print("模拟器中无法打开照相机,请在真机中使用")
            return
        }
        let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
        switch authStatus {
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video) { (granted) in
                if granted {
                    DispatchQueue.main.async {
                        self.selectPhoto()
                    }
                }
            }
        case .restricted, .denied:
            openSettingsURL()
        default:
            switch PHPhotoLibrary.authorizationStatus() {
            case .notDetermined:
                TZImageManager.default()?.requestAuthorization(completion: {
                    self.selectPhoto()
                })
            case .restricted, .denied:
                openSettingsURL()
            default:
                pushImagePickerController()
            }
        }
    }
    
    public func openSettingsURL(){
        STAlertView.show(title: "无法使用相机", message: "请在iPhone的\"设置-隐私-相机\"中允许访问相机", cancelTitle: "取消", otherTitle: "设置", preferredStyle: .alert) { (flag) in
            if flag == 1 {
                let url = URL(string: UIApplication.openSettingsURLString)!
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
            }
        }
    }
    
    public func pushImagePickerController(){
        let pickerController = UIImagePickerController()
        pickerController.sourceType = .camera
        pickerController.delegate = self as UIImagePickerControllerDelegate & UINavigationControllerDelegate
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            fromController.present(pickerController, animated: true, completion:nil)
        }else {
            print("模拟器中无法打开照相机,请在真机中使用")
        }
    }
    var fromController: UIViewController{
        get{
            return UIViewController.topMost ?? UIViewController()
        }
    }
    var imagePickerBlock: ((UIImage) -> ())?
    var imagePickersBlock: (([UIImage]) -> ())?
    var allowCrop:Bool = false
}

extension STImagePicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
    public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true) {
            let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
            let tzImagePickerVc:TZImagePickerController = TZImagePickerController.init(maxImagesCount: 1, delegate: nil)
            tzImagePickerVc.showProgressHUD()
            if self.allowCrop {
                TZImageManager.default()?.savePhoto(with: image, location: nil, completion: { (asset, error) in
                    let assetModel = TZImageManager.default()?.createModel(with: asset)
                    let imagePicker: TZImagePickerController = TZImagePickerController.init(cropTypeWith: assetModel?.asset, photo: image, completion: { [weak self] (cropImage, asset) in
                        self?.imagePickerBlock?(cropImage!)
                    })
                    imagePicker.allowPickingImage = true
                    self.fromController.present(imagePicker, animated: true, completion: nil)
                });
            }else {
                self.imagePickerBlock?(image)
            }
        }
    }
    
    public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
}
